﻿using System.Drawing;

namespace GraphDrawing.Graph.Model
{
    /// <summary>
    /// Интерфейс модели фигуры.
    /// Начало системы координат фигуры располагается в верхнем левом углу (для совместимости с существующими системами координат).
    /// Предполагается, что координаты возвращаемых объектов (<see cref="HitArea"/>) указаны в системе координат фигуры.
    /// </summary>
    public interface IShape
    {
        /// <summary>
        /// Возвращает область, при попадании в которую она может считаться активной.
        /// Может использоваться для приблизительных расчётов попадания точки в область фигуры.
        /// </summary>
        Rectangle HitArea { get; }

        /// <summary>
        /// Выполняет точную проверку попадания точки <paramref name="point"/> в границы фигуры.
        /// </summary>
        /// <param name="point">Координаты тестируемой точки.</param>
        /// <returns>Возвращает true, если точка попадает в границы фигуры, иначе false.</returns>
        bool PreciseHitTest(Point point);
    }

    /// <summary>
    /// Интерфейс модели фигуры, которая может "прикрепляться" к другим фигурам в определённой точке.
    /// </summary>
    public interface IJointedShape : IShape
    {
        /// <summary>
        /// Описывает координаты точки, в которой фигура присоединяется к другой фигуре.
        /// </summary>
        Point Joint { get; }
    }

    /// <summary>
    /// Прямоугольник.
    /// </summary>
    public class RectangleShape : IJointedShape
    {
        /// <summary>
        /// Ширина прямоугольника.
        /// </summary>
        public readonly int width;

        /// <summary>
        /// Высота прямоугольника.
        /// </summary>
        public readonly int height;

        public RectangleShape(int width, int height)
        {
            this.width = width;
            this.height = height;
        }

        public Rectangle HitArea
        {
            get { return new Rectangle(0, 0, width, height); }
        }

        Point IJointedShape.Joint
        {
            get { return new Point(width/2, height/2); }
        }

        bool IShape.PreciseHitTest(Point point)
        {
            return true;
        }
    }

    /// <summary>
    /// Круг.
    /// </summary>
    public class CircleShape : IJointedShape
    {
        /// <summary>
        /// Радиус окружности.
        /// </summary>
        public readonly int radius;

        public CircleShape(int radius)
        {
            this.radius = radius;
        }

        public Point Joint
        {
            get { return new Point(radius, radius); }
        }

        public Rectangle HitArea
        {
            get { return new Rectangle(0, 0, radius*2, radius*2); }
        }

        public bool PreciseHitTest(Point point)
        {
            return true;
        }
    }
}